import React, { useContext, useState } from "react";
import getConfig from "next/config";
import { useRouter } from "next/router";
import Link from "next/link";
import { useCookies } from "react-cookie";
import SEO from "../components/SEO";
import Text from "../components/Text";
import Input from "../components/Input";
import Button from "../components/Button";
import Box from "../components/Box";
import { NotificationContext } from "../components/Notifications";
import LoadingContext from "../utils/LoadingContext";
import LocaleContext from "../utils/LocaleContext";
import { usernamePattern } from "./register";

const Login = () => {
  const [totpRequired, setTotpRequired] = useState(false);

  const [, setCookie] = useCookies();

  const { addNotification } = useContext(NotificationContext);
  const { setLoading } = useContext(LoadingContext);
  const { getLocaleString } = useContext(LocaleContext);

  const router = useRouter();

  const {
    publicRuntimeConfig: { SQ_API_URL },
  } = getConfig();

  const handleLogin = async (e) => {
    e.preventDefault();
    setLoading(true);
    const form = new FormData(e.target);

    try {
      const res = await fetch(`${SQ_API_URL}/login`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          username: form.get("username"),
          password: form.get("password"),
          totp: form.get("totp"),
        }),
      });

      if (res.status !== 200) {
        const reason = await res.text();
        if (reason === "One-time code required") setTotpRequired(true);
        throw new Error(reason);
      }

      const { token, uid, username } = await res.json();

      const expires = new Date();
      expires.setTime(expires.getTime() + 60 * 60 * 24 * 14 * 1000); // 14 days
      setCookie("token", token, { path: "/", expires });
      setCookie("userId", uid, { path: "/", expires });
      setCookie("username", username, { path: "/", expires });

      addNotification(
        "success",
        `${getLocaleString("welcomeBack")} ${form.get("username")}!`
      );

      router.push("/");
    } catch (e) {
      addNotification(
        "error",
        `${getLocaleString("logInFailed")}: ${e.message}`
      );
      console.error(e);
    }

    setLoading(false);
  };

  return (
    <>
      <SEO title={getLocaleString("logIn")} />
      <Box
        display="flex"
        alignItems="center"
        justifyContent="center"
        minHeight="calc(100vh - 140px)"
        py={6}
      >
        <Box
          width="100%"
          maxWidth="400px"
          bg="sidebar"
          borderRadius={2}
          border="1px solid"
          borderColor="border"
          p={6}
          _css={{
            boxShadow: "0 8px 32px rgba(0, 0, 0, 0.1)",
          }}
        >
          <Box textAlign="center" mb={6}>
            <Text as="h1" fontSize={4} fontWeight="600" mb={2} color="text">
              {getLocaleString("logIn")}
            </Text>
            <Text color="grey" fontSize={1}>
              Welcome back to your account
            </Text>
          </Box>

          <Box as="form" onSubmit={handleLogin}>
            <Input
              name="username"
              label={getLocaleString("username")}
              pattern={usernamePattern}
              mb={4}
              required
              _css={{
                transition: "all 0.2s ease",
                "&:focus": {
                  borderColor: "primary",
                  boxShadow: "0 0 0 3px rgba(244, 93, 72, 0.1)",
                },
              }}
            />

            <Input
              name="password"
              type="password"
              label={getLocaleString("password")}
              mb={4}
              required
              _css={{
                transition: "all 0.2s ease",
                "&:focus": {
                  borderColor: "primary",
                  boxShadow: "0 0 0 3px rgba(244, 93, 72, 0.1)",
                },
              }}
            />

            {totpRequired && (
              <Input
                name="totp"
                label={getLocaleString("totp")}
                mb={4}
                required
                _css={{
                  transition: "all 0.2s ease",
                  "&:focus": {
                    borderColor: "primary",
                    boxShadow: "0 0 0 3px rgba(244, 93, 72, 0.1)",
                  },
                }}
              />
            )}

            <Button
              width="100%"
              py={3}
              fontSize={2}
              fontWeight="500"
              _css={{
                background: "linear-gradient(135deg, #000, #ff6b4a)",
                border: "none",
                transition: "all 0.3s ease",
                "&:hover": {
                  background: "linear-gradient(135deg, #e54d38, #000)",
                  transform: "translateY(-1px)",
                  boxShadow: "0 4px 12px rgba(244, 93, 72, 0.3)",
                },
                "&:active": {
                  transform: "translateY(0)",
                },
              }}
            >
              {getLocaleString("logIn")}
            </Button>
          </Box>

          <Box
            textAlign="center"
            mt={5}
            pt={4}
            borderTop="1px solid"
            borderColor="border"
          >
            <Link href="/reset-password/initiate" passHref>
              <Text
                as="a"
                color="primary"
                fontSize={1}
                _css={{
                  textDecoration: "none",
                  transition: "opacity 0.2s ease",
                  "&:hover": {
                    opacity: 0.8,
                    textDecoration: "underline",
                  },
                }}
              >
                {getLocaleString("resetPassword")}
              </Text>
            </Link>
          </Box>
        </Box>
      </Box>
    </>
  );
};

export default Login;
